package com.yrihr.wisdom.controller.reptile;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.yrihr.wisdom.dto.RiverDto;
import com.yrihr.wisdom.entity.River;
import com.yrihr.wisdom.service.RiverService;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.core.strategy.keygen.SnowflakeShardingKeyGenerator;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.constraints.PastOrPresent;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @ClassName : WebRiverController
 * @Description : 爬取河道详情
 * @Author : wind
 * @Date: 2020-12-18 09:03
 * @Version 1.0
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/reptile")
public class WebRiverController {

    private final RiverService riverService;

    @RequestMapping("/river")
    public void river(@RequestBody @NonNull @Validated RiverDto riverDto) throws Exception {
//        String siteName = "安宁渡";
//        String siteId = riverService.selectSiteId(riverDto.getInterval(), siteName);
//        System.out.println(siteId);
        WebClient client = new WebClient(BrowserVersion.FIREFOX_68);
        // 相应选项设置

        // 当JS执行出错的时候是否抛出异常
        client.getOptions().setThrowExceptionOnScriptError(false);
        // 当HTTP的状态非200时是否抛出异常
        client.getOptions().setThrowExceptionOnFailingStatusCode(false);
        client.getOptions().setActiveXNative(false);
        // 很重要，设置支持Ajax
        client.setAjaxController(new NicelyResynchronizingAjaxController());
        client.getOptions().setThrowExceptionOnFailingStatusCode(false);
        client.getOptions().setUseInsecureSSL(true);
        // 是否启用CSS, 因为不需要展现页面, 所以不需要启用
        client.getOptions().setCssEnabled(false);
        client.getOptions().setJavaScriptEnabled(true);
        // 超时
        client.getOptions().setTimeout(30000);
        client.getOptions().setRedirectEnabled(true);
        // 获取某网站页面
        HtmlPage page;
        page = client.getPage("http://10.4.1.9/sqweb/");
        Document doc = null;
        // 开始处理日期循环
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        @PastOrPresent Date start = riverDto.getStartTime();
        @PastOrPresent Date end = riverDto.getEndTime();
        // 返回的日期集合
        List<String> days = new ArrayList<String>();
        Calendar tempStart = Calendar.getInstance();
        tempStart.setTime(start);
        Calendar tempEnd = Calendar.getInstance();
        tempEnd.setTime(end);
        // 日期加1(包含结束)
        tempEnd.add(Calendar.DATE, +1);
        while (tempStart.before(tempEnd)) {
            days.add(sdf.format(tempStart.getTime()));
            tempStart.add(Calendar.DAY_OF_YEAR, 1);
        }
        if (start.before(end) || start.equals(end)) {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//            for(LocalDate currentdate = startDate; currentdate.isBefore(endDate) || currentdate.isEqual(endDate); currentdate= currentdate.plusDays(1)){
            for (String day : days) {
                System.out.println(day);
                long timestamp = System.currentTimeMillis();
                Thread.sleep(5000);
                List<Long> interval = riverDto.getInterval();
                if (interval != null && interval.size() > 0) {
                    for (int i = 0; i < interval.size(); i++) {
                        long intervalId = interval.get(i);
                        String str = "";
                        if (intervalId < 10) {
                            str = "0" + intervalId;
                        }
                        if (intervalId>=10 && intervalId<14) {
                            str = intervalId+"";
                        }
                        // 请求前置地址
                        page = client.getPage(
                                "http://10.4.1.9/sqweb/ActionPage.aspx?ModuleCode=01014&STCDTS=" + str + "&STCDTYPE=00&SDATE="
                                        + day + " 00:00&EDATE=" + day + " 23:59&CXSD=&ROWTYPE=2&username=PUBLIC&GroupID=&timestamp=" + timestamp);
                        // 开始处理html
                        // 开始处理html
                        Parser.xmlParser();
                        Document parse = Jsoup.parse(page.asXml());
                        Element elementById = parse.getElementById("ctl00_rpt");
                        if (elementById != null) {
                            //开始解析
                            try {
                                Elements tr = elementById.getElementsByTag("tr");
                                String riverName = "";
                                String siteName = "";
                                Date time = new Date();
                                SnowflakeShardingKeyGenerator id = new SnowflakeShardingKeyGenerator();
                                for (Element td : tr) {
                                    Elements elementsByTag = td.getElementsByTag("td");
                                    River river = new River();
                                    String update = "select waterLevel from river_details where riverName=? and siteName=? and updateTime=?";
                                    SimpleDateFormat sdfmm = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                                    river.setId((Long) id.generateKey());
                                    //设置区间
                                    river.setIntervalId(intervalId);
                                    try {
                                        if (elementsByTag.get(0).text().isEmpty() && elementsByTag.get(1).text().isEmpty()) {
                                            System.out.println(sdfmm.parse((elementsByTag.get(2).text())));
                                            System.out.println(sdfmm.format(time));
                                            System.out.println(sdfmm.parse((elementsByTag.get(2).text())).after(time));
                                            if (sdfmm.parse((elementsByTag.get(2).text())).after(time)) {
                                                river.setRiverName(elementsByTag.get(0).text().isEmpty() ? riverName : elementsByTag.get(0).text());
                                                river.setSiteName(elementsByTag.get(1).text().isEmpty() ? siteName : elementsByTag.get(1).text());
                                            }

                                        }
                                    } catch (Exception e) {
                                        continue;
                                    }

                                    if (!elementsByTag.get(0).text().isEmpty()) {
                                        river.setRiverName(elementsByTag.get(0).text().isEmpty() ? "" : elementsByTag.get(0).text());
                                    }
                                    if (!elementsByTag.get(1).text().isEmpty()) {
                                        river.setSiteName(elementsByTag.get(1).text().isEmpty() ? "" : elementsByTag.get(1).text());
                                    }
                                    river.setTime(elementsByTag.get(2).text().isEmpty() ? river.getUpdateTime() : sdfmm.parse(elementsByTag.get(2).text()));
                                    river.setUpdateTime(sdfmm.parse(sdfmm.format(new Date())));
                                    riverName = river.getRiverName();
                                    siteName = river.getSiteName();
                                    long siteId = riverService.selectSiteId(intervalId, siteName);
                                    river.setSiteId(siteId);
                                    time = river.getTime();

                                    river.setWaterLevel(elementsByTag.get(4).text().isEmpty() ? 0
                                            : Double.parseDouble(elementsByTag.get(4).text()));
                                    river.setWaterPotential(elementsByTag.get(5).text().isEmpty() ? "" : elementsByTag.get(5).text());
                                    river.setFlow(elementsByTag.get(6).text().isEmpty() ? 0 : Double.parseDouble(elementsByTag.get(6).text()));
                                    QueryWrapper<River> query = Wrappers.query();
                                    query.eq("site_id", river.getSiteId());
                                    query.eq("time", river.getTime());
                                    int count = riverService.count(query);
                                    if (count == 0) {
                                        riverService.save(river);
                                    } else {
                                        // 判断发布时间是否正确
                                        query.ne("water_level", river.getWaterLevel());
                                        count = riverService.count(query);
                                        // 如果找到id=id  其他不同，即count=1，找到了不同，则需要更新
                                        // 如果找到id=id  其他全相同，即结果count=0,没有找到不同，则不更新
                                        // 这两句话太绕了
                                        if (count == 1) {
                                            boolean b = riverService.update(river, query);
                                            log.info("存在：1条记录，id为：" + river.getId() + "但db水位与网站不匹配，则需更新，即将更新！");
                                            if (b) {
                                                log.info("存在：1条记录，id为：" + river.getId() + "但db水位与网站不匹配，已更新成功！");
                                            }
                                        } else {
                                            log.info("存在：1条记录，id为：" + river.getId() + "发布时间与网站匹配，无需更新");
                                        }
                                    }
                                }
                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                                continue;
                            }
                        }
                    }
                }


            }
        }
        // 日期不符合常理
        else {
            log.info("开始时间不小于结束时间");
        }


    }
}
